<template>
      <div ref="holder" class="waves"></div>
</template>

<script setup>
import ShaderProgram from "./index.js"
// 定义默认的pointSize值，你可以根据实际需求调整
const pointSize = ref(2.5);
const holder = ref(null);

// 定义组件接收的props
const props = defineProps({
    texture: {
        type: String,
        default: ''
    },
    uniforms: {
        type: Object,
        default: () => ({
            size: { type: 'float', value: 2.5 },
            field: { type: 'vec3', value: [0, 0, 0] },
            speed: { type: 'float', value: 5 },
        })
    },  
    vertexShader: {
        type: String,
        default: `
        #define M_PI 3.1415926535897932384626433832795
        precision highp float;
        attribute vec4 a_position;
        attribute vec4 a_color;
        uniform float u_time;
        uniform float u_size;
        uniform float u_speed;
        uniform vec3 u_field;
        uniform mat4 u_projection;
        varying vec4 v_color;
        void main() {
          vec3 pos = a_position.xyz;
          pos.y += (
            cos(pos.x / u_field.x * M_PI * 8.0 + u_time * u_speed) +
            sin(pos.z / u_field.z * M_PI * 8.0 + u_time * u_speed)
          ) * u_field.y;
          gl_Position = u_projection * vec4( pos.xyz, a_position.w );
          gl_PointSize = ( u_size / gl_Position.w ) * 100.0;
          v_color = a_color;
        }`
    },
    fragmentShader: {
        type: String,
        default: `
        precision highp float;
        uniform sampler2D u_texture;
        varying vec4 v_color;
        void main() {
          gl_FragColor = v_color * texture2D(u_texture, gl_PointCoord);
        }`
    },
    onUpdate: {
        type: Function,
        default: (delta) => { }
    },
    onResize: {
        type: Function,
        default: (w, h, dpi) => { }
    }
});

// 将props解构为响应式数据
const { texture, uniforms, vertexShader, fragmentShader, onUpdate, onResize } = toRefs(props);

// 用于存储ShaderProgram实例的响应式引用
const shaderProgramInstance = ref(null);

// 创建一个响应式对象来存储组件内部的配置选项，方便传递给ShaderProgram实例
const componentOptions = reactive({
    texture,
    uniforms,
    vertex: vertexShader.value,
    fragment: fragmentShader.value,
    onUpdate,
    onResize
});

onMounted(() => {
    if (holder) {
        shaderProgramInstance.value = new ShaderProgram(holder.value, componentOptions);
    }
});


</script>

<style scoped>
html,
body {
    height: 100%;
}

body {
    margin: 0;
    background: #000;
}

canvas {
    display: block;
}

.waves {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
}
</style>